import 'package:chips_choice/chips_choice.dart';
import 'package:flutter/material.dart';

class TagSelector<T> extends StatefulWidget {
  final List<T> options; // 所有选项
  final List<T> value; // 当前选中值
  final ValueChanged<List<T>> onChanged; // 点击回调
  final bool multiChoice; // 是否多选
  final bool wrapped; // 是否折行
  final double spacing;
  final double runSpacing;
  final Widget Function(BuildContext context, T value, bool selected)
  selectedBuilder;
  final Widget Function(BuildContext context, T value, bool selected)
  unselectedBuilder;

  const TagSelector({
    Key? key,
    required this.options,
    required this.value,
    required this.onChanged,
    required this.selectedBuilder,
    required this.unselectedBuilder,
    this.multiChoice = true,
    this.wrapped = true,
    this.spacing = 8,
    this.runSpacing = 8,
  }) : super(key: key);

  @override
  _TagSelectorState<T> createState() => _TagSelectorState<T>();
}

class _TagSelectorState<T> extends State<TagSelector<T>> {
  late List<T> selected;

  @override
  void initState() {
    super.initState();
    selected = List.from(widget.value);
  }

  void _onTap(T item) {
    setState(() {
      if (widget.multiChoice) {
        // 多选逻辑
        if (selected.contains(item)) {
          selected.remove(item);
        } else {
          selected.add(item);
        }
      } else {
        // 单选逻辑
        selected = [item];
      }
    });
    widget.onChanged(selected);
  }

  @override
  Widget build(BuildContext context) {
    return ChipsChoice<T>.multiple(
      value: selected,
      onChanged: (val) => setState(() => selected = val),
      choiceItems: C2Choice.listFrom<T, T>(
        source: widget.options,
        value: (i, v) => v,
        label: (i, v) => v.toString(),
      ),
      wrapped: widget.wrapped,
      spacing: widget.spacing,
      runSpacing: widget.runSpacing,
      choiceBuilder: (item, index) {
        final T value = item.value;
        final bool isSelected = selected.contains(value);

        final Widget child = isSelected
            ? widget.selectedBuilder(context, value, isSelected)
            : widget.unselectedBuilder(context, value, isSelected);

        return GestureDetector(
          onTap: () => _onTap(value),
          child: Padding(
            padding: EdgeInsets.only(right: widget.spacing),
            child: child,
          ),
        );
      },
    );
  }
}
